package mundo;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class mundo {

	/**
	 * Atributo para el identificador
	 */
	private static String idec;

	/**
	 * Atributo para la ecuacion
	 */
	private static String ecua;

	/**
	 * Atributo para la ecuacion auxiliar
	 */
	private static String ecuaAux = "";

	/**
	 * Atributo para la incognita
	 */
	private static String incog;

	/**
	 * Atributo que llama a la clase nodo
	 */
	private static Nodo nodo;

	/**
	 * Atributo de "a" para ecuaciones cuadraticas
	 */
	private static int a;

	/**
	 * Atributo de "b" para ecuaciones cuadraticas
	 */
	private static int b;

	/**
	 * Atributo de "c" para ecuaciones cuadraticas
	 */
	private static int c;

	/**
	 * Atributo booleano usado en el recorrido para armar el arbol
	 */
	private static boolean check=false;

	/**
	 * Atributo booleano usado para buscar elementos en el arbol
	 */
	private static boolean check2=false;

	/**
	 * Atributo del limite que se pasa en el archivo que se lee.
	 */
	private static int lim;

	/**
	 * Atributo de un contador
	 */
	private static int contador;

	/**
	 * Metodo  que lee el archivo con los datos de la ecuacion a resolver; main de la clase 
	 * @param args
	 * @throws FileNotFoundException 
	 */
	public static void main(String[] args) throws FileNotFoundException {
		// TODO Auto-generated method stub

		File f = new File( "./docs/equ.in" );
		BufferedReader entrada = new BufferedReader( new FileReader( f ) );
		if ( f.exists() )
			try {

				idec = entrada.readLine();
				ecua = entrada.readLine();
				incog = entrada.readLine();
				lim = Integer.parseInt(entrada.readLine()); 
				System.out.println(idec);
				System.out.println(ecua);
				System.out.println(incog);
				System.out.println(lim);


			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} 
			System.out.println("--------------------");
			System.out.println("[0] " + ecua);
			resolverEcua(ecua, lim);


	}
	/**
	 * Metodo que mete la ecuacion en un arreglo de strings y llama el metodo para armar 
	 * el arbol correspondiente a la ecuacion y verifica la ecuacion para tratar el arbol armado.
	 * @param ecuacion
	 * @param limite
	 */
	public static void resolverEcua(String ecuacion, int limite)
	{

		contador = 1;
		String [] listaEcuacion = ecuacion.split(" ");
		armarArbol(listaEcuacion);

		boolean FC = checkFormaCuadritica(nodo);

		if(checkFormaCuadritica(nodo))
		{
			System.out.println("=<S:Conversion Cuadratica>");
			formarCuadratica(nodo);
			System.out.println("[" + contador +"]" +imprimirArbol(nodo));
			contador++;
		}

		if(buscarElementoArbol(nodo, "^2") || FC)
		{

			if(verificarCuadratica(nodo))
			{
				System.out.println("=<S: Regla cuadratica >");
				double[] resp = resolverCuadraticaSimple(a, b, c);
				if(resp[0] == resp[1])
					System.out.println("[" + contador +"]" + incog +" " + (int)resp[0] + " =");
				else
					System.out.println("[" + contador +"]" + incog +" " + (int)resp[0] + " | " + (int)resp[1] + " =");
			}
			if(checkFormaCuadratica2(nodo))
			{
				c = Integer.parseInt(nodo.darhijoI().darhijoD().darElemento());
				System.out.println("=< Al ser de la forma x^2 - a = 0 -> x = rc(a) >");
				double resp = Math.sqrt(c);

				System.out.println("[" + contador +"]" + incog +" " + (int)resp + " =");
			}
		}
		else
		{
			boolean VFS = checkFactorizacionSimple(nodo);
			if(VFS)
			{
				factorizacionSimple(nodo);
				System.out.println("=<S: regla factorizacion Simple >");
				System.out.println("["+contador+"]" + imprimirArbol(nodo));
				contador++;
				ecuaAux = "";
			}
			boolean SRS = checkSumaRestaSimple(nodo);
			if(SRS)
			{
				despejeMasMenosSimple(nodo);
				System.out.println("=<S: x op a = b -> x = b op' a : op{+,-} y op' = - si op = +; op' = + si op = - >");
				System.out.println("["+contador+"]" + imprimirArbol(nodo));
				contador++;
				ecuaAux = "";
			}	
			boolean MDS = checkMultDivisionSimple(nodo);
			if(MDS)
			{
				despejeMultDivSimple(nodo);
				System.out.println("=<S: regla division  multiplicacion simple >");
				System.out.println("["+contador+"]" + imprimirArbol(nodo));
				contador++;
				ecuaAux = "";
			}

		}

	}


	/**
	 * Metodo que arma el arbol binario correspondiente a la ecuacion
	 * @param laEcuacion = la ecuacion leida del archivo
	 */
	public static void armarArbol(String[] laEcuacion)
	{
		nodo = new Nodo(laEcuacion[laEcuacion.length-1]);
		recursion(nodo, laEcuacion, laEcuacion.length-2);	
	}

	/**
	 * Metodo que hace la recursion utilizada para armar el arbol correspondiente a la ecuacion
	 * @param nod
	 * @param ecuacion
	 * @param pos
	 */
	public static void recursion(Nodo nod, String[] ecuacion, int pos )
	{

		if(pos>-1&&!check)
		{
			Nodo aux = new Nodo(ecuacion[pos]);


			if(nod.noHayHijoD())
				nod.agregarHijoD(aux);

			else
			{
				if(nod.noHayHijoI() && nod.darhijoD().noHayHijoI() && nod.darhijoD().esOperadorSimple())
				{
					recursion(nod.darhijoD(),ecuacion,pos);
				}
				if(nod.noHayHijoI() && nod.darhijoD().esOperadorNoSimple() && nod.darhijoD().darhijoD().esOperadorSimple() && nod.darhijoD().darhijoD().noHayHijoI())
				{
					recursion(nod.darhijoD().darhijoD(),ecuacion,pos);
				}
				if(nod.noHayHijoI() && !nod.esOperadorNoSimple())
					nod.agregarHijoI(aux);
				else if(nod.noHayHijoI() && nod.esOperadorNoSimple())
					recursion(nodo,ecuacion,pos);
				else
					if(nod.darhijoI().esOperadorCualquiera())
					{
						recursion(nod.darhijoI(), ecuacion, pos);   
					}
					else
						recursion(nodo,ecuacion,pos);

			}
			if(aux.esOperadorSimple() || aux.darElemento().equals(Nodo.MENOS2))
				recursion(aux,ecuacion, pos-1);

			if(aux.esOperadorNoSimple())
				recursion(aux,ecuacion, pos-1);

			if(!aux.esOperadorSimple()&&!aux.esOperadorNoSimple())
				recursion(nod,ecuacion, pos-1);
		}
		else
		{
			//System.out.println("acabe");
			check=true;
		}

	}

	public static boolean buscarElementoArbol(Nodo nod, String buscado)
	{
		check2=false;
		boolean rta=false;
		if(nod!=null&&check2==false)
		{
			if (nod.darElemento().equals(buscado))
			{
				//System.out.println("check true");
				check2=true;
				rta= true;
			}
			else{
				if(!nodo.esHoja())				

				{
					if(!nodo.noHayHijoD()&&!check2){
						rta= buscarElementoArbol(nod.darhijoD(), buscado);}

					if(!nodo.noHayHijoI()&&!check2){
						rta= buscarElementoArbol(nod.darhijoI(), buscado);}

				}


			}
		}
		return check2;



	}
	/**
	 * Recorrido en Postorden para imprimir el arbol
	 * @param nod
	 * @return
	 */
	public static String imprimirArbol(Nodo nod)
	{
		if(null != nod)
		{
			imprimirArbol(nod.darhijoI());
			imprimirArbol(nod.darhijoD());
			ecuaAux += " " + nod.darElemento();
		}
		return ecuaAux;
	}



	//------------------------------------
	//-------------REGLAS-----------------
	//------------------------------------

	/**
	 * 1. (x/a - x/b) = d -> x*c = d donde c = (1/a - 1/b)
	 * 2. (x/a + x/b) = d -> x*c = d donde c = (1/a + 1/b)
	 */
	public static void factorizacionSimple(Nodo nod)
	{
		if(nod.darhijoI().darElemento().equals(Nodo.MAS))
		{
			if(nod.darhijoI().darhijoI().darElemento().equals(Nodo.DIV))
			{
				double a = Integer.parseInt(nod.darhijoI().darhijoI().darhijoD().darElemento());
				double b = Integer.parseInt(nod.darhijoI().darhijoD().darhijoD().darElemento());
				String[] ecuacionCuad = new String[5];
				ecuacionCuad[0]= incog;
				ecuacionCuad[1]= (1/a + 1/b)+"";
				ecuacionCuad[2]= "*";
				ecuacionCuad[3]= nod.darhijoD().darElemento();
				ecuacionCuad[4]= "=";
				check = false;
				armarArbol(ecuacionCuad);

			}
			if(nod.darhijoI().darhijoI().darElemento().equals(Nodo.MULT))
			{
				double aa = 0;
				double bb = 0;
				if(nod.darhijoI().darhijoI().darhijoI().equals(incog))
				{
					aa = Integer.parseInt(nod.darhijoI().darhijoI().darhijoD().darElemento());
				}
				else if(!nod.darhijoI().darhijoI().darhijoI().equals(incog))
				{
					aa = Integer.parseInt(nod.darhijoI().darhijoI().darhijoI().darElemento());
				}
				else if(nod.darhijoI().darhijoD().darhijoI().equals(incog))
				{
					bb = Integer.parseInt(nod.darhijoI().darhijoD().darhijoD().darElemento());
				}
				else if(!nod.darhijoI().darhijoD().darhijoI().equals(incog))
				{
					bb = Integer.parseInt(nod.darhijoI().darhijoD().darhijoI().darElemento());
				} 
				String[] ecuacionCuad = new String[5];
				ecuacionCuad[0]= incog;
				ecuacionCuad[1]= (1/aa + 1/bb)+"";
				ecuacionCuad[2]= "*";
				ecuacionCuad[3]= nod.darhijoD().darElemento();
				ecuacionCuad[4]= "=";
				check = false;
				armarArbol(ecuacionCuad);
			}
		}
		if(nod.darhijoI().darElemento().equals(Nodo.MENOS))
		{
			if(nod.darhijoI().darhijoI().darElemento().equals(Nodo.DIV))
			{
				double a = Integer.parseInt(nod.darhijoI().darhijoI().darhijoD().darElemento());
				double b = Integer.parseInt(nod.darhijoI().darhijoD().darhijoD().darElemento());
				String[] ecuacionCuad = new String[5];
				ecuacionCuad[0]= incog;
				ecuacionCuad[1]= (1/a - 1/b)+"";
				ecuacionCuad[2]= "*";
				ecuacionCuad[3]= nod.darhijoD().darElemento();
				ecuacionCuad[4]= "=";
				check = false;
				armarArbol(ecuacionCuad);

			}
			if(nod.darhijoI().darhijoI().darElemento().equals(Nodo.MULT))
			{
				double aa = 0;
				double bb = 0;
				if(nod.darhijoI().darhijoI().darhijoI().equals(incog))
				{
					aa = Integer.parseInt(nod.darhijoI().darhijoI().darhijoD().darElemento());
				}
				else if(!nod.darhijoI().darhijoI().darhijoI().equals(incog))
				{
					aa = Integer.parseInt(nod.darhijoI().darhijoI().darhijoI().darElemento());
				}
				if(nod.darhijoI().darhijoD().darhijoI().equals(incog))
				{
					bb = Integer.parseInt(nod.darhijoI().darhijoD().darhijoD().darElemento());
				}
				else if(!nod.darhijoI().darhijoD().darhijoI().equals(incog))
				{
					bb = Integer.parseInt(nod.darhijoI().darhijoD().darhijoI().darElemento());
				} 
				String[] ecuacionCuad = new String[5];
				ecuacionCuad[0]= incog;
				System.out.println(aa);
				System.out.println(bb);
				ecuacionCuad[1]= (1/aa - 1/bb)+"";
				ecuacionCuad[2]= "*";
				ecuacionCuad[3]= nod.darhijoD().darElemento();
				ecuacionCuad[4]= "=";
				check = false;
				armarArbol(ecuacionCuad);
			}
		}
	}

	/**
	 * 1. Si es de la forma (x+a)*(x+a) = 0 -> x^2 + (a+b)*x + (a*b)
	 * 2. Si es de la forma (x-a)*(x-a) = 0 -> x^2 - (a+b)*x + (a*b)
	 * 3. Si es de la forma (x+a)*(x-a) = 0 -> x^2 - (a*b)
	 * 4. Si es de la forma (x-a)*(x+a) = 0 -> x^2 - (a*b)
	 */
	public static void formarCuadratica(Nodo nod)
	{

		if(nod.darhijoI().darhijoD().darElemento().equals(Nodo.MAS) && nod.darhijoI().darhijoI().darElemento().equals(Nodo.MAS))
		{
			if(esNumero(Integer.parseInt(nod.darhijoI().darhijoI().darhijoD().darElemento())) &&  esNumero(Integer.parseInt(nod.darhijoI().darhijoD().darhijoD().darElemento())))
			{
				int AmasB = Integer.parseInt(nod.darhijoI().darhijoI().darhijoD().darElemento()) + Integer.parseInt(nod.darhijoI().darhijoD().darhijoD().darElemento());
				int AporB = Integer.parseInt(nod.darhijoI().darhijoI().darhijoD().darElemento()) * Integer.parseInt(nod.darhijoI().darhijoD().darhijoD().darElemento());
				String[] ecuacionCuad = new String[10];
				ecuacionCuad[0] = incog;
				ecuacionCuad[1] = "^2";
				ecuacionCuad[2] = AmasB+"";
				ecuacionCuad[3] = incog;
				ecuacionCuad[4] = "*";
				ecuacionCuad[5] = "+";
				ecuacionCuad[6] = AporB+"";
				ecuacionCuad[7] = "+";
				ecuacionCuad[8] = "0";
				ecuacionCuad[9] = "=";
				check = false;
				armarArbol(ecuacionCuad);
			}

		}
		else if((nod.darhijoI().darhijoD().darElemento().equals(Nodo.MENOS) && nod.darhijoI().darhijoI().darElemento().equals(Nodo.MENOS)) || (nod.darhijoI().darhijoD().darElemento().equals(Nodo.MENOS) && nod.darhijoI().darhijoI().darElemento().equals(Nodo.MENOS)))
		{
			if(esNumero(Integer.parseInt(nod.darhijoI().darhijoI().darhijoD().darElemento())) &&  esNumero(Integer.parseInt(nod.darhijoI().darhijoD().darhijoD().darElemento())))
			{
				int AmasB = Integer.parseInt(nod.darhijoI().darhijoI().darhijoD().darElemento()) + Integer.parseInt(nod.darhijoI().darhijoD().darhijoD().darElemento());
				int AporB = Integer.parseInt(nod.darhijoI().darhijoI().darhijoD().darElemento()) * Integer.parseInt(nod.darhijoI().darhijoD().darhijoD().darElemento());
				String[] ecuacionCuad = new String[10];
				ecuacionCuad[0] = incog;
				ecuacionCuad[1] = "^2";
				ecuacionCuad[2] = AmasB+"";
				ecuacionCuad[3] = incog;
				ecuacionCuad[4] = "*";
				ecuacionCuad[5] = "-";
				ecuacionCuad[6] = AporB+"";
				ecuacionCuad[7] = "+";
				ecuacionCuad[8] = "0";
				ecuacionCuad[9] = "=";
				check = false;
				armarArbol(ecuacionCuad);
			}
		}
		else if(nod.darhijoI().darhijoD().darElemento().equals(Nodo.MENOS)|| nod.darhijoI().darhijoD().darElemento().equals(Nodo.MENOS2) && nod.darhijoI().darhijoI().darElemento().equals(Nodo.MAS)
				|| nod.darhijoI().darhijoD().darElemento().equals(Nodo.MAS)&& (nod.darhijoI().darhijoI().darElemento().equals(Nodo.MENOS) || nod.darhijoI().darhijoI().darElemento().equals(Nodo.MENOS2)))
		{
			int AporB = Integer.parseInt(nod.darhijoI().darhijoI().darhijoD().darElemento()) * Integer.parseInt(nod.darhijoI().darhijoD().darhijoD().darElemento());
			String[] ecuacionCuad = new String[6];
			ecuacionCuad[0] = incog;
			ecuacionCuad[1] = "^2";
			ecuacionCuad[2] = AporB+"";
			ecuacionCuad[3] = "-";
			ecuacionCuad[4] = "0";
			ecuacionCuad[5] = "=";
			check = false;
			armarArbol(ecuacionCuad);
		}


	}


	/**
	 * Metodo
	 */
	public static void despejeMultDivSimple(Nodo nod)
	{
		Nodo aux1 = nod.darhijoI().darhijoI();
		Nodo aux2 = nod.darhijoI().darhijoD();
		Nodo aux4 = nod.darhijoD();
		if(nod.darhijoI().darElemento().equals(Nodo.MULT))
		{
			Nodo div = new Nodo("/");
			if(!nod.darhijoI().darhijoI().esOperadorCualquiera() && !nod.darhijoI().darhijoD().esOperadorCualquiera())
			{
				if(nod.darhijoI().darhijoI().darElemento().equals(incog) && !aux2.darElemento().equals("0"))
				{
					div.agregarHijoD(aux2);
					div.agregarHijoI(aux4);
					nod.agregarHijoD(div);
					nod.agregarHijoI(aux1);
				}
				else if(nod.darhijoI().darhijoD().darElemento().equals(incog) && !aux1.darElemento().equals("0"))
				{
					div.agregarHijoD(aux1);
					div.agregarHijoI(aux4);
					nod.agregarHijoD(div);
					nod.agregarHijoI(aux2);
				}
				else 
				{
					Nodo cero = new Nodo("0");
					Nodo incognita = new Nodo(incog);
					nod.agregarHijoD(cero);
					nod.agregarHijoI(incognita);
				}
			}
		}
	}


	/**
	 * Metodo de "despeje" de "+" y "-", es decir, si x op a = b -> x = b op' a donde op{+,-} y op' = "-" si op = "+"; op' = "+" si op = "-"
	 * @param nodo
	 */
	public static void despejeMasMenosSimple(Nodo nod)
	{
		Nodo aux1 = nod.darhijoI().darhijoI();
		if(nod.darhijoI().darElemento().equals(Nodo.MAS))
		{
			Nodo negativo = new Nodo("-");
			Nodo aux2 = nod.darhijoI().darhijoD();
			Nodo aux3 = nod.darhijoD();
			//arregla el lado izquierdo
			nod.agregarHijoI(aux1);
			if(nod.darhijoD().darElemento().equals("0"))
			{
				Nodo cero = new Nodo("0");
				nod.agregarHijoD(negativo);
				negativo.agregarHijoD(aux2);
				negativo.agregarHijoI(cero);
				//System.out.println("es mas y es cero y se lo undieron con toda");
			}
			else if(!nod.darhijoD().darElemento().equals("0"))
			{
				nod.agregarHijoD(negativo);
				negativo.agregarHijoD(aux2);
				negativo.agregarHijoI(aux3);
				//System.out.println("es mas y no es cero y se lo undieron con toda");
			}

		}
		else if(nod.darhijoI().darElemento().equals(Nodo.MENOS) || nod.darhijoI().darElemento().equals(Nodo.MENOS2))
		{
			Nodo positivo = new Nodo("+");
			Nodo aux2 = nod.darhijoI().darhijoD();
			Nodo aux3 = nod.darhijoD();
			//arregla el lado izquierdo
			nod.agregarHijoI(aux1);
			if(nod.darhijoD().darElemento().equals("0"))
			{
				Nodo cero = new Nodo("0");
				nod.agregarHijoD(positivo);
				positivo.agregarHijoD(aux2);
				positivo.agregarHijoI(cero);
				//System.out.println("es menos y es cero y se lo undieron con toda");
			}
			if(!nod.darhijoD().darElemento().equals("0"))
			{
				nod.agregarHijoD(positivo);
				positivo.agregarHijoD(aux2);
				positivo.agregarHijoI(aux3);
				//System.out.println("es menos no es cero y se lo undieron con toda");
			}

		}

	}

	/**
	 * Atraccion simple R op R' = R'' donde op{+,-,*,/}
	 * @param nodo = representa un arbol donde evaluan sus elementospara ver si se puede aplicar la regla.
	 */
	public static void atraccionSimple(Nodo nodo)
	{
		//System.out.println("entro Simplificacion");
		if (    !nodo.noHayHijoD()
				&&!nodo.noHayHijoI()&&!nodo.darhijoD().esOperadorCualquiera()&&
				!nodo.darhijoI().esOperadorCualquiera()&& !nodo.darhijoD().darElemento().equals(incog)
				&& !nodo.darhijoI().darElemento().equals(incog))
		{
			if(nodo.darElemento().equals(Nodo.MAS))
			{
				int suma = Integer.parseInt(nodo.darhijoD().darElemento()) + Integer.parseInt(nodo.darhijoI().darElemento());
				nodo.cambiarElemento(suma+"");
				nodo.agregarHijoD(null);
				nodo.agregarHijoI(null);
				System.out.println(nodo.darElemento());
			}
			if(nodo.darElemento().equals(Nodo.MENOS))
			{
				int resta = Integer.parseInt(nodo.darhijoD().darElemento()) - Integer.parseInt(nodo.darhijoI().darElemento());
				nodo.cambiarElemento(resta+"");
				nodo.agregarHijoD(null);
				nodo.agregarHijoI(null);
				System.out.println(nodo.darElemento());
			}
			if(nodo.darElemento().equals(Nodo.MULT))
			{
				int mult = Integer.parseInt(nodo.darhijoD().darElemento()) * Integer.parseInt(nodo.darhijoI().darElemento());
				nodo.cambiarElemento(mult+"");
				nodo.agregarHijoD(null);
				nodo.agregarHijoI(null);
				System.out.println(nodo.darElemento());
			}
			if(nodo.darElemento().equals(Nodo.DIV) && !nodo.darhijoD().darElemento().equals("0"))
			{
				int div = Integer.parseInt(nodo.darhijoI().darElemento()) / Integer.parseInt(nodo.darhijoD().darElemento());
				nodo.cambiarElemento(div+"");
				nodo.agregarHijoD(null);
				nodo.agregarHijoI(null);
				System.out.println(nodo.darElemento());
			}
		}
	}

	/**
	 * Resuelve ecuaciones cuadraticas que sean iguales a "0"
	 * @param aa = "a" de ecuaciones cuadraticas
	 * @param bb = "b" de ecuaciones cuadraticas
	 * @param cc = "c" de acuaciones cuadraticas
	 */
	public static double[] resolverCuadraticaSimple(int aa, int bb, int cc) 
	{
		double respPos = 0;
		double respNeg = 0;
		double[] resp = new double[2];
		double bla = Math.sqrt((bb*bb)-(4*aa*cc));
		respPos = (-bb + bla)/(2*aa);
		respNeg = (-bb - bla)/(2*aa);
		resp[0] = respPos;
		resp[1] = respNeg;
		return resp;

	}


	//------------------------------------
	//----------VERIFICACIONES------------
	//------------------------------------

	public static boolean checkFactorizacionSimple(Nodo nod)
	{
		boolean rta = false;
		if(!nod.noHayHijoI() && nod.darhijoI().darElemento().equals(Nodo.MAS) || nod.darhijoI().darElemento().equals(Nodo.MENOS) || nod.darhijoI().darElemento().equals(Nodo.MENOS2))
		{
			if(nod.darhijoI().darhijoI().darElemento().equals(Nodo.MULT) && 
					nod.darhijoI().darhijoD().darElemento().equals(Nodo.MULT))
			{
				if(!nod.darhijoI().darhijoI().noHayHijoD() && !nod.darhijoI().darhijoI().noHayHijoI() 
						&& !nod.darhijoI().darhijoD().noHayHijoD() && !nod.darhijoI().darhijoD().noHayHijoI())
				{
					if(nod.darhijoI().darhijoI().darhijoI().darElemento().equals(incog) && nod.darhijoI().darhijoD().darhijoI().darElemento().equals(incog) 
							||  nod.darhijoI().darhijoI().darhijoD().darElemento().equals(incog) && nod.darhijoI().darhijoD().darhijoD().darElemento().equals(incog)
							|| nod.darhijoI().darhijoI().darhijoD().darElemento().equals(incog) && nod.darhijoI().darhijoD().darhijoI().darElemento().equals(incog)
							|| nod.darhijoI().darhijoI().darhijoI().darElemento().equals(incog) && nod.darhijoI().darhijoD().darhijoD().darElemento().equals(incog))
					{
						rta = true;
					}
				}
			}
			if( nod.darhijoI().darhijoI().darElemento().equals(Nodo.DIV) && nod.darhijoI().darhijoD().darElemento().equals(Nodo.DIV))
			{
				if(!nod.darhijoI().darhijoI().noHayHijoD() && !nod.darhijoI().darhijoI().noHayHijoI() 
						&& !nod.darhijoI().darhijoD().noHayHijoD() && !nod.darhijoI().darhijoD().noHayHijoI())
				{

					if(nod.darhijoI().darhijoI().darhijoI().darElemento().equals(incog) && nod.darhijoI().darhijoD().darhijoI().darElemento().equals(incog))
					{
						rta = true;
					}

				}
			}
		}
		return rta;
	}


	/**
	 * Verifica si la ecuacion es de tipo ax^2 + b*x + c = 0
	 * @param nodo = representa un arbol donde evaluan sus elementospara ver si se puede aplicar la regla. 
	 * @return boolean = true si es cuadratica; false si no es cuadratica
	 */
	public static boolean verificarCuadratica(Nodo nodo)
	{
		//System.out.println("entro verificacion cuadratica");
		boolean cuad = false;
		//recibe el nodo "="
		if(nodo.darhijoD().darElemento().equals("0"))
		{
			//crea el hijo izquierdo
			Nodo hijo1 = new Nodo(nodo.darhijoI().darElemento());
			//verifica que sea "+" o "-" y que el hijo derecho no sea ningun operador
			if(nodo.darhijoI().darElemento().equals(Nodo.MAS) || nodo.darhijoI().darElemento().equals(Nodo.MENOS) && !nodo.darhijoI().darhijoD().esOperadorCualquiera())
			{
				//Crea el hijo izquierdo del hijo1
				Nodo hijo2 = new Nodo(nodo.darhijoI().darhijoI().darElemento());
				//verifica que el sea "+" o "-" que el hijo derecho sea "*" y el izquierdo "^2"
				if((nodo.darhijoI().darhijoI().darElemento().equals(Nodo.MAS) || 
						nodo.darhijoI().darhijoI().darElemento().equals(Nodo.MENOS)) &&
						(nodo.darhijoI().darhijoI().darhijoD().darElemento().equals(Nodo.MULT) || nodo.darhijoI().darhijoI().darhijoD().darElemento().equals(incog) )
						&& (nodo.darhijoI().darhijoI().darhijoI().darElemento().equals(Nodo.CUAD) ||  (nodo.darhijoI().darhijoI().darhijoI().darElemento().equals(Nodo.MULT))))
				{
					//Crea el hijo izquierdo, es decir "^2"
					Nodo hijo3 = new Nodo(nodo.darhijoI().darhijoI().darhijoI().darElemento());
					//Crea el hijo derecho, es decir "*"
					Nodo hijo4 = new Nodo(nodo.darhijoI().darhijoI().darhijoD().darElemento());
					//Verifica que el hijo derecho de "^2" sea la incognita y que el hijo derecho de "*" se la incognita y que el hijo izquierdo de "*" no sea un operador
					if(nodo.darhijoI().darhijoI().darhijoI().darhijoD().darElemento().equals(incog) && 
							nodo.darhijoI().darhijoI().darhijoD().darhijoD().darElemento().equals(incog) && 
							!nodo.darhijoI().darhijoI().darhijoD().darhijoI().esOperadorCualquiera())
					{
						cuad = true;
						a = 1;
						//System.out.println("es cuadratica con a = 1");
						//si hijo2 = a menos asigna -b, b de lo contrario
						if(nodo.darhijoI().darhijoI().darElemento().equals(Nodo.MENOS))
						{
							//System.out.println("b negativo");
							b = -Integer.parseInt(nodo.darhijoI().darhijoI().darhijoD().darhijoI().darElemento());
						}
						else
							b = Integer.parseInt(nodo.darhijoI().darhijoI().darhijoD().darhijoI().darElemento());
						//si hijo1 = a menos asigna -c, c de lo contrario
						if(nodo.darhijoI().darElemento().equals(Nodo.MENOS))
							c = -Integer.parseInt(nodo.darhijoI().darhijoD().darElemento());
						else
							c = Integer.parseInt(nodo.darhijoI().darhijoD().darElemento());

					}
					//Si el hijo derecho de hijo3 es multiplicacion es porque a !=0 pero positivo y verifica que el hijo derecho de dicha multiplacion sea la incognita
					if(     nodo.darhijoI().darhijoI().darhijoI().darElemento().equals(Nodo.MULT) &&
							nodo.darhijoI().darhijoI().darhijoI().darhijoD().darhijoD().darElemento().equals(incog) && 
							!nodo.darhijoI().darhijoI().darhijoI().darhijoI().esOperadorCualquiera() &&
							nodo.darhijoI().darhijoI().darhijoI().darhijoD().darElemento().equals(Nodo.CUAD))
					{
						//System.out.println("es cuadratica con a != 1");
						cuad = true;
						a = Integer.parseInt(nodo.darhijoI().darhijoI().darhijoI().darhijoI().darElemento());

						if(nodo.darhijoI().darhijoI().darElemento().equals(Nodo.MENOS))
							b = -Integer.parseInt(nodo.darhijoI().darhijoI().darhijoD().darhijoI().darElemento());
						else
							b = Integer.parseInt(nodo.darhijoI().darhijoI().darhijoD().darhijoI().darElemento());
						//si hijo1 = a menos asigna -c, c de lo contrario
						if(nodo.darhijoI().darElemento().equals(Nodo.MENOS))
							c = -Integer.parseInt(nodo.darhijoI().darhijoD().darElemento());
						else
							c = Integer.parseInt(nodo.darhijoI().darhijoD().darElemento());
					}
				}
			}
		}
		return cuad;

	}

	/**
	 * Metodo que verifica si un arbol que representa una ecuacion cuadratica es correcto forma (xopa)*(xopb) donde op{+,-}
	 * @param elNodo = representa un arbol donde evaluan sus elementospara ver si se puede aplicar la regla.
	 * @return booleano true si es correcto, de lo contrario false
	 */
	public static boolean checkFormaCuadritica(Nodo elNodo)
	{
		boolean rta = false;
		if(!elNodo.noHayHijoD()&&!elNodo.noHayHijoI())
			if(elNodo.darhijoD().darElemento().equals("0")&&elNodo.darhijoI().darElemento().equals(Nodo.MULT));
		if(!elNodo.darhijoI().noHayHijoD()&&!elNodo.darhijoI().noHayHijoI())
			if(elNodo.darhijoI().darhijoD().darElemento().equals(Nodo.MAS)||elNodo.darhijoI().darhijoD().darElemento().equals(Nodo.MENOS)&&elNodo.darhijoI().darhijoI().darElemento().equals(Nodo.MAS)||elNodo.darhijoI().darhijoI().darElemento().equals(Nodo.MENOS))
				if(!elNodo.darhijoI().darhijoI().noHayHijoI()&&!elNodo.darhijoI().darhijoI().noHayHijoD()&&!elNodo.darhijoI().darhijoD().noHayHijoI()&&!elNodo.darhijoI().darhijoD().noHayHijoD())
					if(elNodo.darhijoI().darhijoI().darhijoI().darElemento().equals(incog)||elNodo.darhijoI().darhijoI().darhijoD().darElemento().equals(incog)&&elNodo.darhijoI().darhijoD().darhijoI().darElemento().equals(incog)||elNodo.darhijoI().darhijoD().darhijoD().darElemento().equals(incog))
						rta=true;
		//System.out.println("la ecuacion es tiene forma cuadratica : "+rta);		
		return rta;
	}

	/**
	 * Metodo que verifica si un arbol que representa una ecuacion cuadratica es correcto forma x^2-a = 0
	 * @param elNodo = representa un arbol donde evaluan sus elementospara ver si se puede aplicar la regla.
	 * @return booleano true si es correcto, de lo contrario false
	 */
	public static boolean checkFormaCuadratica2(Nodo nod)
	{
		boolean rta = false;
		if(!nod.noHayHijoD() && !nod.noHayHijoI())
		{
			if(nod.darhijoD().darElemento().equals("0") &&  nod.darhijoI().darElemento().equals(Nodo.MENOS))
			{
				if(!nod.darhijoI().noHayHijoI() && !nod.darhijoI().darhijoI().noHayHijoD())
				{
					if(nod.darhijoI().darhijoI().darElemento().equals("^2") && nod.darhijoI().darhijoI().darhijoD().darElemento().equals(incog))
						rta = true;
				}
			}
		}
		return rta;
	}

	/**
	 * Metodo que reviza si se puede "pasar" un mas o menos que no involucre la incognita; del lado izquierdo al lado derecho del arbol  
	 * @param nod = nodo de inicio de checkeo
	 * @return booleano = true si se puede pasar; false de lo contrario
	 */
	public static boolean checkSumaRestaSimple(Nodo nod)
	{	
		boolean resp = false;
		if(!nod.noHayHijoI() && !nod.darhijoI().noHayHijoD() && nod.darhijoI().darElemento().equals(Nodo.MAS) || nod.darhijoI().darElemento().equals(Nodo.MENOS) || nod.darhijoI().darElemento().equals(Nodo.MENOS2) && !nod.darhijoI().darhijoD().esOperadorCualquiera() && !nod.darhijoI().darhijoD().darElemento().equals(incog))
		{
			resp = true;
		}
		return resp;
	}

	/**
	 * Metodo que reviza si se puede pazar una multiplicacacion o una division puede involucre la incognita; del lado izquierdo al lado derecho del arbol
	 * @param nod = nodo de inicio de checkeo
	 * @return booleano = true si se puede pasar; false de lo contrario
	 */
	public static boolean checkMultDivisionSimple(Nodo nod)
	{
		boolean resp = false;
		if(!nod.noHayHijoI() && nod.darhijoI().darElemento().equals(Nodo.MULT) || nod.darhijoI().darElemento().equals(Nodo.DIV) && !nod.darhijoI().darhijoD().esOperadorCualquiera() && !nod.darhijoI().darhijoI().esOperadorCualquiera())
		{
			resp = true;
		}
		return resp;
	}

	/**
	 * Verifica si algo es un numero del 1 al 9.
	 * @param entero
	 * @return boolean true si lo es, false caso contrario
	 */
	public static boolean esNumero(int entero)
	{
		boolean resp = false;
		if(entero == 1 || entero == 2 ||entero == 3 ||entero == 4 ||entero == 5 ||entero == 6 ||entero == 7 ||entero == 8 ||entero == 9)
		{
			resp = true;
		}
		return resp;
	}



}
